import { Chart, type ChartConfiguration, type ChartData, type ChartDataset, type FinancialDataPoint, type ScaleOptions } from 'chart.js'; // Import the Chart.js types if not already done
import 'chartjs-adapter-luxon'; // This line imports the adapter
import { DateTime } from 'luxon';
import type { IndicatorActionWrap, Kline, KlineFlat, LSMAv, MAv, ValueWrapper } from './bindings';
import { GLOBAL_CHART_DATA, calculateVolumeBackgroundColor, calculateVolumeBorderColor, formatNumberToString, getLsmaValueByPeriod, getMaValueByPeriod, isInvalidContext, updateAxisScale, upsertDataset } from './FudaChartApi';



export const CandleChartConfig = {
    data: {
        datasets: [
            {
                label: 'Volume',
                type: 'bar' as const,
                data: [],
                yAxisID: 'y-volume',
                backgroundColor: (context: any) => calculateVolumeBackgroundColor(context),
                borderColor: (context: any) => calculateVolumeBorderColor(context),
                borderWidth: 1,
                hoverBorderWidth: 6,
            }, {
                label: 'Price',
                type: 'candlestick' as const,
                data: [],
                yAxisID: 'y-price',
                backgroundColors: {
                    up: '#FF0000', // Red for price up
                    down: '#00FF00', // Green for price down
                    unchanged: 'gray', // Optional color for unchanged
                },
                borderColors: {
                    up: '#FF0000', // Red border for price up
                    down: '#00FF00', // Green border for price down
                    unchanged: 'gray', // Optional border color for unchanged
                },
                borderWidth: 1,
                hoverBorderWidth: 6,
            },

        ]
    },
    options: {
        animation: false,
        spanGaps: true, // enable for all datasets
        responsive: true,
        maintainAspectRatio: false,
        scales: {
            'y-volume': {
                type: 'linear' as const,
                position: 'left' as const,
                // display: false, // Add this to hide the scale initially
                grid: {
                    lineWidth: function (context: any) {
                        if (context.tick && typeof context.tick.value !== 'undefined' && context.tick.value === context.scale.min) {
                            return 3
                        }
                        return 1
                    },
                },
                ticks: {
                    callback: function (value: number, index: any, ticks: any) {
                        // Format price axis labels
                        return formatNumberToString(value)
                    },
                },
                stack: 'candle',
                stackWeight: 1,
                beginAtZero: false,
                grace: '1%', // Optional: Adds a bit of padding around min/max

            }, 'y-price': {
                type: 'linear' as const,
                position: 'left' as const,
                // display: false, // Add this to hide the scale initially
                grid: {
                    lineWidth: function (context: any) {
                        if (context.tick && typeof context.tick.value !== 'undefined' && context.tick.value === context.scale.min) {
                            return 3
                        }
                        return 1
                    },
                },
                ticks: {
                    callback: function (value: number, index: any, ticks: any) {
                        // Format price axis labels
                        return formatNumberToString(value)
                    },
                },
                stack: 'candle',
                stackWeight: 3,
                beginAtZero: false,
                grace: '1%', // Optional: Adds a bit of padding around min/max

            },
            // Define 'boll-axis' and 'y-macd' similarl
            // Ensure that the x-axis for candlesticks remains visible
            x: {

                type: 'timeseries' as const,
                display: true,
                time: {
                    // unit: 'day' as const,
                    displayFormats: {
                        second: 'HH:mm:ss',
                        minute: 'HH:mm',
                        hour: 'MM dd, HH:mm',
                        day: 'MM dd',
                        week: 'll', // Example format for weeks, adjust as needed
                        month: 'MMM yy',
                        quarter: '[Q]QQQ yy',
                        year: 'yy',
                    },
                },
                border: {
                    display: false
                },
                grid: {
                    display: true,
                    drawOnChartArea: true,
                    drawTicks: true,
                },
                ticks: {
                    minRatation: 50,
                    maxRotation: 50,
                    sampleSize: 10,
                },
            },
        },
        plugins: {
            legend: {
                display: false, // Disable the built-in legend
            },
            tooltip: {
                enabled: false, // Disable default tooltip if you want to handle tooltip separately
                mode: 'index' as const,
            },
            zoom: {
                zoom: {
                    wheel: {
                        enabled: false,
                    },
                    drag: {
                        enabled: true,
                    },
                    pinch: {
                        enabled: true,
                    },
                    mode: 'x' as const,
                    scaleMode: 'x' as const,
                },
            },
            title: {
                display: false,
                text: 'Day Kline',
            }
        },
    },
}


export const IndicatorChartConfig = {
    data: {
        datasets: [
            {
                label: 'y0',
                type: 'line' as const,
                data: [],
                yAxisID: 'y0' as const,
                backgroundColor: 'rgba(128, 0, 128, 0.3)', // Bright purple for Bollinger Bands line
                borderColor: 'rgb(128, 0, 128)', // Solid bright purple for borders
                borderWidth: 1,
                pointRadius: 0,
                fill: false,
                hoverBorderWidth: 5,
                hoverBorderColor: 'green',
            }, {
                label: 'y1',
                type: 'line' as const,
                data: [],
                yAxisID: 'y1' as const,
                backgroundColor: 'rgba(128, 0, 128, 0.3)', // Bright purple for Bollinger Bands line
                borderColor: 'rgb(128, 0, 128)', // Solid bright purple for borders
                borderWidth: 1,
                pointRadius: 0,
                fill: false,
                hoverBorderWidth: 5,
                hoverBorderColor: 'green',
            }, {
                label: 'y2',
                type: 'line' as const,
                data: [],
                yAxisID: 'y2' as const,
                backgroundColor: 'rgba(128, 0, 128, 0.3)', // Bright purple for Bollinger Bands line
                borderColor: 'rgb(128, 0, 128)', // Solid bright purple for borders
                borderWidth: 1,
                pointRadius: 0,
                fill: false,
                hoverBorderWidth: 5,
                hoverBorderColor: 'green',
            }, {
                label: 'y3',
                type: 'line' as const,
                data: [],
                yAxisID: 'y3' as const,
                backgroundColor: 'rgba(128, 0, 128, 0.3)', // Bright purple for Bollinger Bands line
                borderColor: 'rgb(128, 0, 128)', // Solid bright purple for borders
                borderWidth: 1,
                pointRadius: 0,
                fill: false,
                hoverBorderWidth: 5,
                hoverBorderColor: 'green',
            },
        ],
    },
    options: {
        animation: false,
        spanGaps: true, // enable for all datasets
        responsive: true,
        maintainAspectRatio: false,
        scales: {
            y0: {
                type: 'linear' as const,
                position: 'left' as const,
                // display: false, // Add this to hide the scale initially
                grid: {
                    lineWidth: function (context: any) {
                        if (context.tick && typeof context.tick.value !== 'undefined' && context.tick.value === context.scale.min) {
                            return 3
                        }
                        return 1
                    },
                },
                ticks: {
                    callback: function (value: number, index: any, ticks: any) {
                        // Format price axis labels
                        return formatNumberToString(value)
                    },
                },
                stack: 'indicator',
                stackWeight: 1,
                beginAtZero: false,
                // grace: '1%', // Optional: Adds a bit of padding around min/max
            },
            y1: {
                type: 'linear' as const,
                position: 'left' as const,
                // display: false, // Add this to hide the scale initially
                grid: {
                    lineWidth: function (context: any) {
                        if (context.tick && typeof context.tick.value !== 'undefined' && context.tick.value === context.scale.min) {
                            return 3
                        }
                        return 1
                    },
                },
                ticks: {
                    callback: function (value: number, index: any, ticks: any) {
                        // Format price axis labels
                        return formatNumberToString(value)
                    },
                },
                stack: 'indicator',
                stackWeight: 1,
                beginAtZero: false,
                grace: '1%', // Optional: Adds a bit of padding around min/max
            },
            y2: {
                type: 'linear' as const,
                position: 'left' as const,
                // display: false, // Add this to hide the scale initially
                grid: {
                    lineWidth: function (context: any) {
                        if (context.tick && typeof context.tick.value !== 'undefined' && context.tick.value === context.scale.min) {
                            return 3
                        }
                        return 1
                    },
                },
                ticks: {
                    callback: function (value: number, index: any, ticks: any) {
                        // Format price axis labels
                        return formatNumberToString(value)
                    },
                },
                stack: 'indicator',
                stackWeight: 1,
                beginAtZero: false,
                grace: '1%', // Optional: Adds a bit of padding around min/max
            }, y3: {
                type: 'linear' as const,
                position: 'left' as const,
                // display: false, // Add this to hide the scale initially
                grid: {
                    lineWidth: function (context: any) {
                        if (context.tick && typeof context.tick.value !== 'undefined' && context.tick.value === context.scale.min) {
                            return 3
                        }
                        return 1
                    },
                },
                ticks: {
                    callback: function (value: number, index: any, ticks: any) {
                        // Format price axis labels
                        return formatNumberToString(value)
                    },
                },
                stack: 'indicator',
                stackWeight: 1,
                beginAtZero: false,
                grace: '1%', // Optional: Adds a bit of padding around min/max
            },

            x: {

                type: 'timeseries' as const,
                display: true,
                time: {
                    displayFormats: {
                        second: 'HH:mm:ss',
                        minute: 'HH:mm',
                        hour: 'MM dd, HH:mm',
                        day: 'MM dd',
                        week: 'll', // Example format for weeks, adjust as needed
                        month: 'MMM yy',
                        quarter: '[Q]QQQ yy',
                        year: 'yy',
                    },
                },
                border: {
                    display: false
                },
                grid: {
                    display: true,
                    drawOnChartArea: true,
                    drawTicks: true,
                },
                ticks: {
                    minRatation: 50,
                    maxRotation: 50,
                    sampleSize: 10,
                },
            },
        },
        plugins: {
            legend: {
                display: false, // Display the built-in legend
            },
            tooltip: {
                enabled: false, // Disable default tooltip if you want to handle tooltip separately
                mode: 'index' as const,
            },
            zoom: {
                zoom: {
                    wheel: {
                        enabled: false,
                    },
                    drag: {
                        enabled: true,
                    },
                    pinch: {
                        enabled: true,
                    },
                    mode: 'x' as const,
                    scaleMode: 'x' as const,
                },
            },
            title: {
                display: false,
                text: 'Indicators: ADX,AROON etc.',
            },
            // annotation: {
            //     annotations: {
            //         adxLabel: {
            //             type: 'label',
            //             scaleID: 'y0', // This corresponds to your first y-axis (y0)
            //             xValue: 100, // Position at the end of the x-axis
            //             yValue: 1.1, // Slightly above the maximum value to ensure visibility (adjust as needed)
            //             xAdjust: -10, // Adjust label to the right
            //             yAdjust: -10, // Adjust label upwards
            //             backgroundColor: 'rgba(245,245,245,0.8)', // Semi-transparent background
            //             content: 'ADX', // The label text
            //             font: {
            //                 size: 14,
            //                 weight: 'bold',
            //             },
            //             display: true,
            //             drawTime: 'afterDatasetsDraw', // Ensure labels are drawn on top of datasets
            //         },
            //         macdLabel: {
            //             type: 'label',
            //             scaleID: 'y1', // This corresponds to your second y-axis (y1)
            //             xValue: 100,
            //             yValue: 1.1,
            //             xAdjust: -10,
            //             yAdjust: -10,
            //             backgroundColor: 'rgba(245,245,245,0.8)',
            //             content: 'MACD',
            //             font: {
            //                 size: 14,
            //                 weight: 'bold',
            //             },
            //             display: true,
            //             drawTime: 'afterDatasetsDraw',
            //         },
            //         // Repeat for y2 and y3 with appropriate content and scaleIDs
            //         // ...
            //     },
            // },
        },
    },
}


export function upsertChartPrice(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    let start = DateTime.now()
    // Prices data
    let prices: FinancialDataPoint[] = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        o: kline.open,
        h: kline.high,
        l: kline.low,
        c: kline.close,
    }))
    let end1 = DateTime.now()

    upsertDataset(chart, GLOBAL_CHART_DATA, 'Price', prices, yAxisID)
    let end2 = DateTime.now()

    console.log("upsertChartPrice end1-start(second)= ", end1.diff(start).toMillis() / 1000, " end2-end1(second)= ", end2.diff(end1).toMillis() / 1000)
    // Check if chart options and scales exist, and safely access yAxisID scale
    if (chart.options?.scales?.[yAxisID]) {
        // Update the scale configuration safely
        chart.options.scales[yAxisID] = {
            ...(chart.options.scales[yAxisID] ?? {}),
            min: Math.min(...prices.map((candle) => candle.l)) ?? undefined, // Use nullish coalescing to avoid overwriting with undefined
            max: Math.max(...prices.map((candle) => candle.h)) ?? undefined,
        };
    }

}

export function upsertChartVolume(chart: Chart, klines: KlineFlat[], yAxisID: string) {
    // Volume成交量

    let volumes = klines.map((kline) => ({
        x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
        y: Number(kline.volume),
        o: kline.open,
        h: kline.high,
        l: kline.low,
        c: kline.close,
    }));
    upsertDataset(chart, GLOBAL_CHART_DATA, 'Volume', volumes, yAxisID)

    updateAxisScale(chart, yAxisID, [volumes]);
}


export function upsertChartTrendLine(chart: Chart, klines: Kline[], yAxisID: string) {
    if (klines && klines.length > 0) {
        // close收盘价

        let line_klines = klines.map((kline) => ({
            x: DateTime.fromISO(kline.klts).setZone('utc').valueOf(),
            y: Number(kline.close),
        }));

        console.log("upsertChartTrendLine line_klines=", line_klines);

        upsertDataset(chart, GLOBAL_CHART_DATA, 'trend_lines', line_klines, yAxisID)


    }
}
